using System;
using System.Collections.Generic;
using System.Text;
using da = Microsoft.ConnectionEngine.Registers.Core.ServiceProvider.DataAccess;
using Microsoft.ConnectionEngine.Registers.Core.ServiceProvider.Common.DataSets;
using Microsoft.ConnectionEngine.Registers.Core.ServiceProvider.Common;


namespace Microsoft.ConnectionEngine.Registers.Core.ServiceProvider.Business
{
    /// <summary>
    /// Provides Business Logic for Pool operations, including CRUD.
    /// </summary>
    public static class PoolManager
    {
        
        //Work Item ID: 1278
        //Modified By: SachinJo
        //updated this class as static and commented the public constructor, 
        //this class consists of only static members and thus creating an instance is of no use.
        //#region Constructor

        ///// <summary>
        ///// Default constructor
        ///// </summary>
        //public PoolManager() { }

        //#endregion

        #region Get/search methods
        /// <summary>
        /// Gets a list of all Pools
        /// </summary>
        /// <returns>A collection of pool objects</returns>
        public static Pools PoolSearch(PoolSearchRequest poolSearchRequest)
        {
            Pools pools = new Pools();
            dsPool ds = da.Pool.PoolSearch(poolSearchRequest.DisplayName, poolSearchRequest.ServiceProviderTypeID, poolSearchRequest.ServiceProviderID, poolSearchRequest.InServiceProvider);

            foreach (dsPool.PoolRow dr in ds.Pool)
            {
                Pool currentPool = new Pool();
                currentPool.PoolID = Convert.ToInt32(dr.poolID);
                currentPool.PoolName = dr.poolName;
                pools.PoolList.Add(currentPool);
            }
            return pools;
        }

        /// <summary>
        /// Gets a specific Pool by ID
        /// </summary>
        /// <param name="poolid">The ID of the Pool to retrieve</param>
        /// <returns>A Pool object representing the requested Pool</returns>
        public static Pool PoolSelectItem(string poolID)
        {
            return PoolSelectItem(poolID, true);
        }

        /// <summary>
        /// Gets a specific Pool by ID
        /// </summary>
        /// <param name="poolid">The id of the Pool to retrieve</param>
        /// <param name="getLists">A boolean that indicates if the returned Pool should be populated with the children Service Providers.</param>
        /// <returns>A Pool object representing the requested Pool and/or children Service Providers</returns>
        public static Pool PoolSelectItem(string poolID, bool getLists)
        {
            Pool currentPool = new Pool();
            dsPool ds = da.Pool.PoolSelectItem(poolID);
            dsPool.PoolRow dr = ds.Pool[0];

            currentPool.PoolID = int.Parse(dr.poolID);
            currentPool.PoolName = dr.poolName;

            if (getLists)
            {
                ServiceProviderSearchRequest providerSearchRequest = new ServiceProviderSearchRequest();
                providerSearchRequest.PoolID = poolID;
                currentPool.ServiceProviders = ServiceProviderManager.ServiceProviderSearch(providerSearchRequest).Items;                
            }

            return currentPool;
        }
       

        #endregion

        #region Insert/Update methods

        /// <summary>
        /// Updates a pool
        /// </summary>
        /// <param name="pool">The pool to be updated</param>
        /// <param name="userID">The user that needs to have the pool locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolUpdate(Pool pool, string userID)
        {
            // return error if object is not already checked out to provider
            if (!da.Pool.PoolIsLockedByUser(pool.PoolID.ToString(), userID)) return "10";


            if (!da.Pool.PoolExists(pool.PoolName))
            {
                // return error if can't update 
                if (!da.Pool.PoolUpdate(pool.PoolID.ToString(), pool.PoolName))
                {
                    return "99";    // can't update
                }
            }
            else
            {
                return "99";
            }

            // otherwise, return successful
            return "0";
        }


        /// <summary>
        /// Inserts a pool
        /// </summary>
        /// <param name="pool">The ID of the Pool to be instered</param>
        /// <param name="userID">The user that has the object locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolInsert(Pool pool, string userID)
        {
            string newPoolID = string.Empty;

            if (!da.Pool.PoolExists(pool.PoolName))
            {

                newPoolID = da.Pool.PoolInsert(pool.PoolName);

                // set id to value returned from insert 
                pool.PoolID = int.Parse(newPoolID);               
                
            }
            // return error if insert failed (i.e didn't return a new key)
            //Work Item ID: 1598
            //Modified By: SachinJo
            //if (newPoolID == "") return "99";
            if (string.IsNullOrEmpty(newPoolID)) return "99";
           
            // otherwise, return successful
            return "0";
        }

        #endregion

        #region Delete methods

        /// <summary>
        /// Deletes a pool
        /// </summary>
        /// <param name="poolID">The service provider to be deleted</param>
        /// <param name="userID">The user that has the object locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolDelete(string poolID, string userID)
        {
            // return error if object is not already checked out to provider
            if (!da.Pool.PoolIsLockedByUser(poolID, userID)) return "10";

            // return error if can't delete poolpool children
            if (!da.Pool.ServiceProviderPoolDeleteByPoolID(poolID)) return "99";

            // return error if can't delete PoolServiceProviderType children
            if (!da.PoolServiceProviderType.PoolServiceProviderTypeDeleteByPoolID(poolID)) return "99"; // can't delete children

            // return error if can't delete 
            if (!da.Pool.PoolDelete(poolID)) return "99";    // can't delete

            // otherwise, return successful
            return "0";
        }

        #endregion

        #region Check in/out methods

        /// <summary>
        /// Locks a pool
        /// </summary>
        /// <param name="poolID">The pool to be locked</param>
        /// <param name="userID">The user that has the object locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolLock(string poolID, string userID)
        {
            // return error if object is already checked out

            if (da.Pool.PoolIsLocked(poolID))
            {
                if (da.Pool.PoolIsLockedByUser(poolID, userID))
                    return "0";
                else
                    return "9";                
            }
            // return error if check out fails
            if (!da.Pool.PoolLock(poolID, userID)) return "99";

            // otherwise, return successful
            return "0";
        }


        /// <summary>
        /// Unlocks a pool
        /// </summary>
        /// <param name="poolID">The pool that is to be locked</param>
        /// <param name="userID">The user that should have the pool locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolUnlock(string poolID, string userID)
        {
            // return error if object is not already checked out to provider
            if (!da.Pool.PoolIsLockedByUser(poolID, userID)) return "10";

            // return error if check in fails
            if (!da.Pool.PoolUnlock(poolID)) return "99";

            // otherwise, return successful
            return "0";
        }


        /// <summary>
        /// Unlocks all pools locked by a specific user
        /// </summary>
        /// <param name="userID">The user that has the objects locked</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolUnlockAll(string userID)
        {
            // return error if check in fails
            if (!da.Pool.PoolUnlockAll(userID)) return "99";

            // otherwise, return successful
            return "0";
        }

        #endregion


        #region PoolServiceProviderType Methods

        /// <summary>
        /// Search for PoolServiceProviderType based on the search criteria.
        /// </summary>
        /// <param name="poolID">The unique identifier of the Pool to be searched for.</param>
        /// <param name="serviceProviderTypeID">The unique identifier of the Service Provider Type to be searched for.</param>
        /// <returns>A list of PoolServiceProviderTypes that match the search criteria.</returns>
        public static PoolServiceProviderTypes PoolServiceProviderTypeSearch(string poolID, string serviceProviderTypeID)
        {
            PoolServiceProviderTypes poolspts = new PoolServiceProviderTypes();
            dsPoolServiceProviderType ds =
                da.PoolServiceProviderType.PoolServiceProviderTypeSearch(poolID, serviceProviderTypeID);

            foreach (dsPoolServiceProviderType.PoolServiceProviderTypeRow dr in ds.PoolServiceProviderType)
            {
                PoolServiceProviderType currentPoolspt = new PoolServiceProviderType();
                currentPoolspt.Pool = new Pool(int.Parse(dr.poolID), dr.poolName);
                currentPoolspt.ServiceProviderType =
                    new ServiceProviderType(int.Parse(dr.serviceProviderTypeID), dr.serviceProviderTypeDisplayName, dr.serviceProviderTypeCode);

                poolspts.Items.Add(currentPoolspt);
            }

            return poolspts;
        }

        /// <summary>
        /// Adds a service provider type to a pool
        /// </summary>
        /// <param name="poolID">The unique identifier of the Pool to be added</param>
        /// <param name="serviceProviderTypeID">The unique identifier of the Service Provider Type to be added</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolServiceProviderTypeInsert(int poolID, int serviceProviderTypeID)
        {           
            // if new row doesn't exist, attempt to insert
            if (!da.PoolServiceProviderType.PoolServiceProviderTypeExists(poolID.ToString(), serviceProviderTypeID.ToString()))
            {
                // if unable to insert, return error.
                if (!da.PoolServiceProviderType.PoolServiceProviderTypeInsert(poolID.ToString(), serviceProviderTypeID.ToString())) return "99";
            }

            // otherwise, return successful
            return "0";
        }


        /// <summary>
        /// Insert a list of PoolServiceProviderTypes passed as a parameter.
        /// </summary>
        /// <param name="poolsptLinks">The list of PoolServiceProviderTypes to be inserted.</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolServiceProviderTypeLinkInsert(PoolServiceProviderTypeLinks poolsptLinks)
        {
            string result = "0";
            foreach (PoolServiceProviderTypeLink poolsptLink in poolsptLinks.Items)
            {
                string status = PoolServiceProviderTypeInsert(poolsptLink.PoolID, poolsptLink.ServiceProviderTypeID);
                if (status != "0") result = status;
            }
            // otherwise, return successful
            return result;
        }

        /// <summary>
        /// Removes a service provider from a pool
        /// </summary>
        /// <param name="poolID">The unique identifier of the Pool to be removed</param>
        /// <param name="serviceProviderTypeID">The unique identifier of the Service Provider Type to be removed</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string  PoolServiceProviderTypeDelete(int poolID, int serviceProviderTypeID)
        {            
            // return error if can't delete 
            if (!da.PoolServiceProviderType.PoolServiceProviderTypeDelete(poolID.ToString(), serviceProviderTypeID.ToString())) return "99";

            // otherwise, return successful
            return "0";
        }

        /// <summary>
        /// Insert a list of PoolServiceProviderTypes passed as a parameter.
        /// </summary>
        /// <param name="poolsptLinks">The list of PoolServiceProviderTypes to be added.</param>
        /// <returns>A status code ("0" is successful)</returns>
        public static string PoolServiceProviderTypeLinkDelete(PoolServiceProviderTypeLinks poolsptLinks)
        {
            string result = "0";
            foreach (PoolServiceProviderTypeLink poolsptLink in poolsptLinks.Items)
            {
                string status = PoolServiceProviderTypeDelete(poolsptLink.PoolID, poolsptLink.ServiceProviderTypeID);
                if (status != "0") result = status;
            }
            // otherwise, return successful
            return result;
        }

        #endregion

    }

}
